package main

import (
	"errors"
	"fmt"
	"math"
	"strconv"
	"strings"
)

//VIP个人信息结构体
type VipUser struct {
	//用户名
	name string
	//性别
	sex float64
	//身高
	height float64
	//体重
	weight float64
	//年龄
	age float64
	//体重指数BMI值
	BMI float64
	//体脂率BFR值
	BFR float64
	//体脂率排名
	TOP_num int
}

//普通用户信息结构体
type GeneralUser struct {
	//用户名
	name string
	//性别
	sex float64
	//身高
	height float64
	//体重
	weight float64
	//年龄
	age float64
	//体重指数BMI值
	BMI float64
	//体脂率BFR值
	BFR float64
}

//用户操作接口
type UserAction interface {
	//展示用户信息
	ShowUserInfo()
	//创建新用户
	MakeUser()
	//登录用户通过用户名
	LoginUser()
	//展示体脂率TOP排行榜
	ShowBFRTOP()
	//设置排名
	SetTOP()
}

var (
	//引用接口
	userAction UserAction

	//VIP用户存储数组
	vipusers = make(map[int]VipUser)

	//普通用户数组
	users []GeneralUser

	//VIP用户排名切片
	vipTOP []int

	//当前用户是否是vip
	IsVip bool

	//当前VIP用户
	nowvipuser VipUser

	//当前普通用户
	nowuser GeneralUser

	//登录状态
	islogin = false

	//工具数组
	utilarr   = []string{"请输入正确的参数", "输入0退出", "无权限", "输入0返回上一级", "重新输入信息请输入:reload", "输入exit返回上一级"}
	inutilarr = []string{"输入姓名," + utilarr[5] + "," + utilarr[4], "输入年龄," + utilarr[5] + "," + utilarr[4], "输入性别," + utilarr[5] + "," + utilarr[4], "输入身高," + utilarr[5] + "," + utilarr[4], "输入体重," + utilarr[5] + "," + utilarr[4]}
)

func main() {
	fmt.Println("系统启动")
	fmt.Println("欢迎使用体脂率查询系统")
	fmt.Println("***************************************************************************")

	root()
}

//新建VIP用户创建接口
func (vipuser *VipUser) MakeUser() {
	vipuser.BMI = vipuser.weight / math.Pow(vipuser.height/100, 2)
	vipuser.BFR = (1.2*vipuser.BMI + 0.23*vipuser.age - 5.4 - 10.8*vipuser.sex) / 100
}

//展示VIP用户信息
func (vipuser VipUser) ShowUserInfo() {
	fmt.Println("=========================")
	fmt.Println("姓名:", vipuser.name)
	fmt.Println("年龄:", vipuser.age)
	var sex string
	switch vipuser.sex {
	case 1:
		sex = "男"
	case 0:
		sex = "女"
	}
	fmt.Println("性别:", sex)
	fmt.Println("身高:", vipuser.height)
	fmt.Println("体重:", vipuser.weight)
	fmt.Printf("体重指数:%2.3f \n", vipuser.BMI)
	fmt.Printf("体脂率:%2.3f \n", vipuser.BFR)
	fmt.Println("您目前体脂率在VIP中排在第", vipuser.TOP_num, "名,请继续努力!!")
	fmt.Println("=========================")
}

//登录VIP用户通过用户名
func (vipuser VipUser) LoginUser() {
	for _, val := range vipusers {
		if val.name == vipuser.name {
			nowvipuser = val
			islogin = true
			IsVip = true
		}
	}
}

//设置VIP用户排行
func (vipuser VipUser) SetTOP() {
	if len(vipTOP) != 0 {
		numtemp := len(vipTOP)
		for i := 0; i < len(vipTOP); i++ {
			if vipusers[vipTOP[i]].BFR > vipuser.BFR {
				temp := vipusers[vipTOP[i]]
				vipusers[vipTOP[i]] = vipuser
				vipuser.TOP_num = vipTOP[i]
				vipTOP = append(vipTOP, numtemp+1)
				for j := i + 1; j < len(vipTOP); j++ {
					temps := vipusers[vipTOP[j]]
					vipusers[vipTOP[j]] = temp
					temp = temps
				}
				break
			}
		}
		if len(vipTOP) == numtemp {
			vipTOP = append(vipTOP, numtemp+1)
			vipuser.TOP_num = numtemp + 1
			vipusers[numtemp+1] = vipuser
		}
	} else {
		vipTOP = append(vipTOP, 1)
		vipuser.TOP_num = 1
		vipusers[1] = vipuser
	}
}

//展示体脂率TOP排行榜
func (vipuser VipUser) ShowBFRTOP() {
	for i := 0; i < len(vipTOP); i++ {
		fmt.Printf("第 %v 名 -- %v 体脂率: %2.3f \n", vipTOP[i], vipusers[vipTOP[i]].name, vipusers[vipTOP[i]].BFR)
		if vipTOP[i] == vipuser.TOP_num {
			fmt.Println("<==  您的位置")
		}
	}
}

//新建普通用户创建接口
func (guser *GeneralUser) MakeUser() {
	guser.BMI = guser.weight / math.Pow(guser.height/100, 2)
	guser.BFR = (1.2*guser.BMI + 0.23*guser.age - 5.4 - 10.8*guser.sex) / 100
}

//展示普通用户信息
func (guser GeneralUser) ShowUserInfo() {
	fmt.Println("=========================")
	fmt.Println("姓名:", guser.name)
	fmt.Println("年龄:", guser.age)
	var sex string
	switch guser.sex {
	case 1:
		sex = "男"
	case 0:
		sex = "女"
	}
	fmt.Println("性别:", sex)
	fmt.Println("身高:", guser.height)
	fmt.Println("体重:", guser.weight)
	fmt.Printf("体重指数:%2.3f \n", guser.BMI)
	fmt.Printf("体脂率:%2.3f \n", guser.BFR)
	fmt.Println("=========================")
}

//普通用户通过用户名登录
func (guser GeneralUser) LoginUser() {
	for i := 0; i < len(users); i++ {
		if users[i].name == guser.name {
			nowuser = users[i]
			islogin = true
			IsVip = false
		}
	}
}

//系统主体
func root() {
	for {
		if GoRun() {
			fmt.Println("系统关闭 bye bye")
			break
		}
	}
}

//系统输入
func GoRun() bool {
	var isExit = false
	for {
		if !islogin {
			for {
				var a int
				fmt.Println("您尚未登录,输入1新建用户,输入2登录,", utilarr[1])
				_, err := fmt.Scan(&a)
				if err != nil {
					a = 3
				}
				switch a {
				case 1:
					Register()
					if islogin {
						fmt.Println("注册成功正在登录。。。")
						Logined()
					}
				case 2:
					Login()
					if islogin {
						fmt.Println("正在登录。。。")
						Logined()
					}
				case 0:
					isExit = true
				default:
					fmt.Println(utilarr[0])
				}
				fmt.Println(isExit)
				if isExit {
					break
				}
			}
		}
		if isExit {
			break
		}
	}
	return isExit
}

//用户注册
func Register() {
	var isbreak = false
	var vipuser VipUser
	var guser GeneralUser
	for {
		var a int
		var err error
		fmt.Println("新建VIP用户输入1,新建普通输入2,", utilarr[3])
		a, err = fmt.Scan(&a)
		if err != nil {
			a = 3
		}
		switch a {
		case 1:
			vipuser, isbreak = inputVipUser()
			if isbreak {
				break
			}
			vipuser.MakeUser()
			vipuser.SetTOP()
			vipuser.LoginUser()
		case 2:
			guser, isbreak = inputGeneralUser()
			if isbreak {
				break
			}
			guser.MakeUser()
			users = append(users, guser)
			guser.LoginUser()
		case 0:
			isbreak = true
		default:
			fmt.Println("err")
			fmt.Println(utilarr[0])
		}
		if isbreak || islogin {
			break
		}
	}
}

//用户登录
func Login() {
	var vipuser VipUser
	var guser GeneralUser
	var isExit = false
	for {
		var a int
		var isbreak = false
		for {
			fmt.Println("VIP用户输入1,普通用户输入2,", utilarr[3])
			_, err := fmt.Scan(&a)
			if err != nil {
				a = 3
			}
			switch a {
			case 1:
				for {
					fmt.Println("输入用户名", utilarr[3])
					fmt.Scan(&vipuser.name)
					if vipuser.name == "0" {
						isbreak = true
					}
					vipuser.LoginUser()
					if islogin {
						break
					}
				}
			case 2:
				for {
					fmt.Println("输入用户名", utilarr[3])
					fmt.Scan(&guser.name)
					if guser.name == "0" {
						isbreak = true
					}
					guser.LoginUser()
					if islogin {
						break
					}
				}
			case 0:
				isExit = true
			default:
				fmt.Println(utilarr[0])
			}
			if isbreak || isExit || islogin {
				break
			}
		}
		if islogin {
			break
		}
	}
}

//用户登录后界面
func Logined() {
	fmt.Println("***********************************")
	fmt.Println("登录成功！！")
	var Loginout = false
	for {
		var a int
		if IsVip {
			fmt.Println("当前用户: ", nowvipuser.name)
			fmt.Println("***********************************************")
			fmt.Println("输入1 查看个人信息,输入2 查看排行榜,输入0 注销用户")
			_, err := fmt.Scan(&a)
			if err != nil {
				a = 3
			}
			switch a {
			case 1:
				nowvipuser.ShowUserInfo()
			case 2:
				nowvipuser.ShowBFRTOP()
			case 0:
				Loginout = true
			default:
				fmt.Println(utilarr[0])
			}
		} else {
			fmt.Println("当前用户: ", nowuser.name)
			fmt.Println("***********************************************")
			nowuser.ShowUserInfo()
			fmt.Println("输入0 注销用户")
			fmt.Scan(&a)
			switch a {
			case 0:
				Loginout = true
			default:
				fmt.Println(utilarr[0])
			}
		}
		if Loginout {
			islogin = false
			IsVip = false
			break
		}
	}
}

//VIP输入工具
func inputVipUser() (VipUser, bool) {
	var isExit = false
	var vipuser VipUser
	var err error
	var strarr []string = make([]string, len(inutilarr))
	for i := 0; i < len(inutilarr); i++ {
		fmt.Println(inutilarr[i])
		fmt.Scan(&strarr[i])
		if strings.Contains(strarr[i], "exit") {
			isExit = true
			break
		}
		if strings.Contains(strarr[i], "reload") {
			i = 0
			continue
		}
		switch i {
		case 0:
			vipuser.name = strarr[i]
		case 1:
			vipuser.age, err = strconv.ParseFloat(strarr[i], 64)
		case 2:
			switch strarr[i] {
			case "男":
				vipuser.sex = 1
			case "女":
				vipuser.sex = 0
			case "1":
				vipuser.sex, err = strconv.ParseFloat(strarr[i], 64)
			case "0":
				vipuser.sex, err = strconv.ParseFloat(strarr[i], 64)
			default:
				err = errors.New("参数不存在")
			}
		case 3:
			vipuser.height, err = strconv.ParseFloat(strarr[i], 64)
		case 4:
			vipuser.weight, err = strconv.ParseFloat(strarr[i], 64)
		}
		if err != nil {
			fmt.Println(utilarr[0])
			i--
		}
	}
	return vipuser, isExit
}

//普通用户输入工具
func inputGeneralUser() (GeneralUser, bool) {
	var isExit = false
	var vipuser GeneralUser
	var err error
	var strarr []string = make([]string, len(inutilarr))
	for i := 0; i < len(inutilarr); i++ {
		fmt.Println(inutilarr[i])
		fmt.Scan(&strarr[i])
		if strings.Contains(strarr[i], "exit") {
			isExit = true
			break
		}
		if strings.Contains(strarr[i], "exit") {
			isExit = true
			break
		}
		switch i {
		case 0:
			vipuser.name = strarr[i]
		case 1:
			vipuser.age, err = strconv.ParseFloat(strarr[i], 64)
		case 2:
			switch strarr[i] {
			case "男":
				vipuser.sex = 1
			case "女":
				vipuser.sex = 0
			case "1":
				vipuser.sex, err = strconv.ParseFloat(strarr[i], 64)
			case "0":
				vipuser.sex, err = strconv.ParseFloat(strarr[i], 64)
			default:
				err = errors.New("参数不存在")
			}
		case 3:
			vipuser.height, err = strconv.ParseFloat(strarr[i], 64)
		case 4:
			vipuser.weight, err = strconv.ParseFloat(strarr[i], 64)
		}
		if err != nil {
			fmt.Println(utilarr[0])
			i--
		}
	}
	return vipuser, isExit
}
